/****************************************************************************
**
** Copyright (C) 2015 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing/
**
** This file is part of the demonstration applications of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL21$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see http://www.qt.io/terms-conditions. For further
** information use the contact form at http://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 or version 3 as published by the Free
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
** LICENSE.LGPLv3 included in the packaging of this file. Please review the
** following information to ensure the GNU Lesser General Public License
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** As a special exception, The Qt Company gives you certain additional
** rights. These rights are described in The Qt Company LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include <QApplication>
#include <math.h>
#include <QSqlDatabase>
#include <QDebug>
#include <stdint.h>
#include <assert.h>
#include <thread>
#include <string>
#include <windows.h>
#include "mapwidget.h"
#include "Transport/UDPdriver.h"
#include "common_struct/FlightPathMassage.h"
#include "trackdataparser.h"

const int data_length_in = 1240;
const int max_packet_count_in = 50;
const int local_port = 5567;
const int max_track_cnt = (data_length_in-sizeof(MagicNumberInfo))*max_packet_count_in/sizeof(Track_Out);
int udp_recv_cnt = 0;
MapWidget* window;
bool connect(const QString &dbName)
{
    QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");
    db.setDatabaseName(dbName);
    if (!db.open()) {
        qDebug() << "Database Error!";
        return false;
    }
    return true;
}

#if 1
void TargetMessageRefresh(void)
{
    uint8_t buffer_in[data_length_in];
    uint8_t buffer[data_length_in*max_packet_count_in];
    memset(buffer_in, 0x00, data_length_in);

    //received magic number
    int identifer = 0xAAAAAAAA;

    char received_packet_count = 0;
    char received_packet_seq = 0;
    short received_track_count = 0;
    short received_point_count = 0;
    int received_frame_seq = 0;
    MagicNumberInfo magic_number_in;
    TrackDataParser* dataparser = new TrackDataParser();
    CUDPdriver* UDPServer = new CUDPdriver();
    Targets_Info* data = (Targets_Info*)malloc(sizeof(Targets_Info));
    data->target = (TargetMessageStruct*)malloc(sizeof(TargetMessageStruct)*max_track_cnt);
    UDPServer->listen(local_port);

    while(1)
    {
        UDPServer->recv_data(buffer_in, data_length_in);

        memset(buffer, 0x0, sizeof(uint8_t)*data_length_in*max_packet_count_in);
        memcpy(&magic_number_in, buffer_in, sizeof(magic_number_in));

        if((magic_number_in.Identifer == identifer) && (magic_number_in.FrameType == enum_track_data))
        {
#if 1

            received_track_count = magic_number_in.Point_cnt;
            received_packet_count = magic_number_in.UDP_cnt;
            received_packet_seq = magic_number_in.UDP_Seq;
            received_packet_seq++;
            received_frame_seq = magic_number_in.FrameSeq;
            qDebug() << "received_frame_seq = " << received_frame_seq;
            udp_recv_cnt++;
            qDebug() << "udp_recv_cnt = " << udp_recv_cnt;
            memcpy(buffer, buffer_in+sizeof(MagicNumberInfo), data_length_in-sizeof(MagicNumberInfo));
            for(int i=1;i<received_packet_count; i++)
            {
                UDPServer->recv_data(buffer_in, data_length_in);
                udp_recv_cnt++;
                qDebug() << "udp_recv_cnt = " << udp_recv_cnt;
                memcpy(&magic_number_in, buffer_in, sizeof(MagicNumberInfo));
                //if(magic_number_in.UDP_Seq == received_packet_seq)
                if(magic_number_in.FrameSeq == received_frame_seq)
                {
                    memcpy(buffer + i*(data_length_in - sizeof(MagicNumberInfo)), buffer_in + sizeof(MagicNumberInfo), data_length_in-sizeof(MagicNumberInfo));
                    received_packet_seq++;
                }
               if(magic_number_in.UDP_Seq == (magic_number_in.UDP_cnt-1))
                    break;
            }

            dataparser->parseTrackData_FromUDP(buffer, sizeof(Track_Out)*received_track_count, data->target, received_track_count);

            data->frame = magic_number_in.FrameSeq;
            window->refresh_track(data,received_track_count);

#endif
        }
        else if((magic_number_in.Identifer == identifer) && (magic_number_in.FrameType == enum_point_data))
        {
#if 1
            received_point_count = magic_number_in.Point_cnt;
            received_packet_count = magic_number_in.UDP_cnt;
            received_packet_seq = magic_number_in.UDP_Seq;
            received_packet_seq++;
            memcpy(buffer, buffer_in+sizeof(MagicNumberInfo), data_length_in-sizeof(MagicNumberInfo));
            for(int i=1;i<received_packet_count; i++)
            {
                UDPServer->recv_data(buffer_in, data_length_in);
                memcpy(&magic_number_in, buffer_in, sizeof(MagicNumberInfo));
                if(magic_number_in.UDP_Seq == received_packet_seq){
                    memcpy(buffer + i*(data_length_in - sizeof(MagicNumberInfo)), buffer_in + sizeof(MagicNumberInfo), data_length_in-sizeof(MagicNumberInfo));
                    received_packet_seq++;
                }
                if(magic_number_in.UDP_Seq == (magic_number_in.UDP_cnt-1))
                    break;
            }
            dataparser->parserPointData_FromUDP(buffer, sizeof(Point_In)*received_point_count, data->target, received_point_count);
            data->frame = magic_number_in.FrameSeq;
            window->refresh_target(data,received_point_count);
#endif
        }
    }
}

#else
void TargetMessageRefresh()
{
    Sleep(2000);
    TargetMessageStruct* target = NULL;
    uint32_t count = 5;
    target = (TargetMessageStruct*)malloc(sizeof(TargetMessageStruct) * count);
    Targets_Info* target_test = NULL;
    target_test = (Targets_Info*)malloc(sizeof(Targets_Info));

    int counter = 0;
    int interval = 0;
    while(1)
    {
        //5个目标
        if(interval%25==0){
            interval=0;
        }

        for(uint32_t i=0; i<count; i++)
        {
            target[i].BatchID = 1+i;
            target[i].Distance = 30 * interval ;
            target[i].Speed = 0;
            target[i].Angle = (i*30);
            target[i].Amp = 0;
            target[i].Radius = 0;
            target[i].CourseAngle = 0;
            qDebug() << "angle = " << target[i].Angle;

        }

        interval++;
        target_test->frame = counter;
        target_test->target = target;

        if(counter%25<5)
            window->refresh_track(target_test, 0);
        else
            window->refresh_track(target_test, count);

        for(uint32_t i=0; i<count; i++)
        {
            target[i].BatchID = 1+i;
            target[i].Distance = 30 * interval +7;
            target[i].Speed = 0;
            target[i].Angle = (i*30);
            target[i].Amp = 0;
            target[i].Radius = 0;
            target[i].CourseAngle = 0;

        }
        window->refresh_target(target_test, count);

        counter++;
        Sleep(500);
    }

    free(target);
    target = NULL;
    free(target_test);
    target_test = NULL;
}
#endif

int main(int argc, char *argv[])
{
    qDebug() << QSqlDatabase::drivers();
    if(connect("test.db")){
        qDebug() << "Database Create Sucessfully!";
    }
    else{
        qDebug() << "Database Create Failed!";
    }

    Q_INIT_RESOURCE(images);
    QApplication app(argc, argv);
    app.setAttribute(Qt::AA_DontCreateNativeWidgetSiblings);

    window = new MapWidget();
    std::thread *tmp = new std::thread(TargetMessageRefresh);
    window->show();
    app.exec();
    tmp->join();
    return 0;

}

